<?php
/**
 *
 * @author ninteySeven.
 * @date 2023-03-26 11:41
 */

namespace App\Services;

use App\Enum\AirportEnum;
use App\Enum\BalanceLogEnum;
use App\Enum\BannerEnum;
use App\Enum\DriverEnum;
use App\Enum\OrderEnum;
use App\Enum\TravelEnum;
use App\Enum\VehicleConfigEnum;
use App\Enum\VillagerEnum;
use App\Enum\WalletsEnum;
use App\Http\Clients\ShuMaiDataClient;
use App\Lib\Jwt;
use App\Lib\sms\AliSms;
use App\Models\AdminConfigModel;
use App\Models\AirportModel;
use App\Models\BalanceLogModel;
use App\Models\BannerModel;
use App\Models\ConfigModel;
use App\Models\DriverModel;
use App\Models\DriverRealModel;
use App\Models\FeedbackModel;
use App\Models\OrderModel;
use App\Models\UserCommunityModel;
use App\Models\VehicleConfigModel;
use App\Models\VillagerUserCommunityModel;
use App\Models\VillagerUserModel;
use App\Models\WalletModel;
use App\Services\Interfaces\CommonInterface;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Log;
use OSS\Core\OssException;
use OSS\OssClient;

class CommonService extends BaseService implements CommonInterface
{

    public $appId = null;

    public $appKey = null;

    public function __construct()
    {
        $this->appId = env('WECHAT_APP_ID');
        $this->appKey = env('WECHAT_KEY');
    }

    /**
     * 二维码核销-出行订单
     * codeOrderOrd
     * @throws Exception
     * @author ninetyseven.
     * @date 2023/5/14
     */
    public static function codeOrderOrd(int $orderId = 0,int $driverId = 0): array
    {
        if (empty($orderId)) {
            throw new Exception('订单id不能为空');
        }

        $orderInfo = OrderModel::query()->where('id', $orderId)->first();
        if (!$orderInfo) {
            throw new Exception('订单不存在');
        }
        if (!in_array($orderInfo->status, [OrderEnum::STATUS_PICKUP_ARRIVED, OrderEnum::STATUS_DRIVING,OrderEnum::STATUS_SUCCESS])) {
            throw new Exception('订单状态不正确');
        }
        if($driverId && $orderInfo->driver_id != $driverId){
            throw new Exception('司机信息不正确');
        }

        $info = true;
        $nowTime = time();
        $type = TravelEnum::QRCODE_TYPE_VILLAGER_INFO;

        //普通订单
        switch ($orderInfo->status) {
            case OrderEnum::STATUS_PICKUP_ARRIVED:// 到达接客点
                //司机扫码,开始行程,改变订单状态为行驶中
                $type = TravelEnum::QRCODE_TYPE_ORD;
                $orderInfo->status = OrderEnum::STATUS_DRIVING;
                $orderInfo->ord_start_time = time();
                $info = $orderInfo->save();
                if (!$info) {
                    throw new Exception('订单状态修改失败');
                }
                break;
            case OrderEnum::STATUS_DRIVING:
                $type = TravelEnum::QRCODE_TYPE_ORD_END;

                $orderTime = timeDiff($nowTime, $orderInfo->start_time)['min'];
                // 修改订单状态
                $orderInfo->status = OrderEnum::STATUS_SUCCESS;
                $orderInfo->end_time = $nowTime;
                $orderInfo->order_time = max($orderTime, 0);
                $orderInfo->travel_amount = $orderInfo->amount;

                $info = $orderInfo->save();
                if (!$info) {
                    throw new Exception('订单状态修改失败');
                }
                break;
            case OrderEnum::STATUS_SUCCESS:
                throw new Exception('订单已经核销成功。');

        }

        return [
            'type' => $type,
            'order_info' => $info,
            'user_info' => VillagerUserModel::query()->where('id', $orderInfo->user_id)->first(),
            'result' => $orderInfo,
        ];
    }



    /**
     * 二维码核销-活动订单
     * codeActivityOrderOrd
     * @param int $activityId
     * @return array
     * @throws Exception
     * @author ninetyseven.
     * @date 2023/5/14
     */
    public static function codeActivityOrderOrd(int $activityId = 0, $orderId=0): array
    {
        if (empty($activityId)) {
            throw new Exception('活动ID不能为空');
        }

        $orderList = OrderModel::query()
            ->where('activity_id', $activityId);
        if( !empty($orderId))$orderList->where('id','=', $orderId);
        $orderList = $orderList->get();
        if (empty($orderList)) {
            throw new Exception('活动订单不存在');
        }
        $orderList = $orderList->toArray();

        $info = true;
        $type = TravelEnum::QRCODE_TYPE_VILLAGER_INFO;

        $orderIds = array_column($orderList, 'id');
        $orderInfo = reset($orderList);
        //活动订单核销
        switch ($orderInfo['status']) {
            case OrderEnum::STATUS_PICKUP_ARRIVED:// 活动订单:开始行程,改变订单状态为行驶中
                //司机扫码,开始行程,改变订单状态为行驶中
                $type = TravelEnum::QRCODE_TYPE_ORD;

                $update = [
                    'status' => OrderEnum::STATUS_DRIVING,
                    'ord_start_time' => time()

                ];
                $info = OrderModel::query()->whereIn('id', $orderIds)->update($update);
                if (!$info) {
                    throw new Exception('订单状态修改失败');
                }
                break;
            case OrderEnum::STATUS_DRIVING:
                // 活动订单:结束行程,改变订单状态为已完成
                $type = TravelEnum::QRCODE_TYPE_ORD_END;

                //订单核销
//                $info = (new DriverService())->writeActivityOffOrder($orderList);
                $info = (new DriverService())->ordActivityOrder($orderId);
                if (!$info) {
                    throw new Exception('订单核销失败');
                }
                break;
        }

        return [
            'type' => $type,
            'order_info' => $info,
            'user_info' => VillagerUserModel::query()->where('id', $orderInfo['user_id'])->first(),
            'result' => $orderInfo,
        ];
    }

    /**
     * 登录
     * @param array $params
     * @throws Exception
     * @author ninteySeven.
     * @date 2023-03-26 11:42
     */
    public function accountLogin(array $params = [])
    {
        $account = $params['account'] ?? '';
        $password = $params['password'] ?? '';
        if (empty($account) || empty($password)) {
            throw new Exception('参数不能为空');
        }

        $info = DriverModel::where('phone', $account)->where('password', md5Password($password))->first();
        if (!$info) {
            throw new Exception('账号或密码错误');
        }
        if ($info->status == VillagerEnum::ACCOUNT_STATUS_CANCELLATION) {
            throw new Exception('账号已注销');
        }

        // 村委会/居委会
        if (in_array($info['identity'], [TravelEnum::PLATFORM_VILLAGER_COMMITTEE, TravelEnum::PLATFORM_MEMBER_VILLAGER])) {
            $info['is_check_community'] = false;
            $info['status'] = VillagerEnum::STATE_WAIT;

            //检查是否审核通过
            $community = UserCommunityModel::query()
                ->where('user_id', $info['id'])
                ->where('user_type', $info['identity'])
                ->where('community_id', self::getPlatformId())
                ->where('status', VillagerEnum::ACCOUNT_STATUS_OK)
                ->first();
            if ($community) {
                $info['is_check_community'] = true;
                $info['status'] = VillagerEnum::ACCOUNT_STATUS_OK;
            }
        }

        $token = Jwt::createToken($info->id);
        $info['token'] = $token;
        $info['platform_id'] = TravelEnum::PLATFORM_DRIVER;

        return $info;
    }

    /**
     * 手机号登录
     * @param array $params
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-03-26 15:17
     */
    public function telLogin(array $params = [])
    {
        $phone = $params['tel'] ?? '';
        $code = $params['code'] ?? '';
        $openid = $params['open_id'] ?? '';

        if (empty($phone) || empty($code)) {
            throw new Exception('参数不能为空');
        }

        //验证验证码
        list($ok, $errMsg) = AliSms::smsCheck($phone, $code, 'LOGIN');
        if (!$ok) {
            throw new Exception($errMsg);
        }

        if ($params['platform_type'] == 1) {
            //司机
            $where[] = ['phone', '=', $phone];
            $where[] = ['state', '=', VillagerEnum::ACCOUNT_STATUS_OK];

            $info = DriverModel::query()->where($where)->first();
            if (!$info) {
                Log::error(sprintf("司机sms登录，Phone=%s, state=%d,",$phone,VillagerEnum::ACCOUNT_STATUS_OK));
                throw new Exception('司机信息不存在');
            }

            $info['is_enterprise'] = !empty($info->enterprise_id);
            $info['platform_id'] = TravelEnum::PLATFORM_DRIVER;
        } else {
            if (!empty($openid)) {
                $where[] = ['open_id', '=', $openid];
            } else {
                $where[] = ['phone', '=', $phone];
            }
            $info = VillagerUserModel::query()->where($where)->first();

            //不存在,则是捐款方
            if (!$info) {
                $info = VillagerUserModel::query()->create([
                    'phone' => $phone,
                    'is_foreign' => VillagerEnum::FOREIGN,
                    'open_id' => $openid,
                    'identity' => TravelEnum::PLATFORM_DONATION,
                ]);
                if (!$info) {
                    throw new Exception('更新失败');
                }
                $info['platform_id'] = TravelEnum::PLATFORM_DONATION;
            } else {
                $obj = VillagerUserModel::query();
                if (!empty($openid)) {
                    $obj->where('open_id', $openid);
                } else {
                    $obj->where('phone', $phone);
                }
                $info = $obj->update([
                    'is_settlein' => VillagerEnum::SETTLE_IN,
                    'phone' => $phone,
                    'identity' => TravelEnum::PLATFORM_DONATION,
                ]);
                if (!$info) {
                    throw new Exception('更新失败');
                }

                $obj = VillagerUserModel::query();
                if (!empty($openid)) {
                    $obj->where('open_id', $openid);
                } else {
                    $obj->where('phone', $phone);
                }
                $info = $obj->first();
            }
        }

        if ($info['status'] == VillagerEnum::ACCOUNT_STATUS_CANCELLATION) {
            throw new Exception('账号已注销');
        }

        // 村委会/居委会
        if (in_array($info['identity'], [TravelEnum::PLATFORM_VILLAGER_COMMITTEE, TravelEnum::PLATFORM_MEMBER_VILLAGER])) {
            $info['is_check_community'] = false;
            $info['status'] = VillagerEnum::STATE_WAIT;

            //检查是否审核通过
            $community = UserCommunityModel::query()
                ->where('user_id', $info['id'])
                ->where('user_type', $info['identity'])
                ->where('community_id', self::getPlatformId())
                ->where('status', VillagerEnum::ACCOUNT_STATUS_OK)
                ->first();
            if ($community) {
                $info['is_check_community'] = true;
                $info['status'] = VillagerEnum::ACCOUNT_STATUS_OK;
            }
        }

        $token = Jwt::createToken($info['id']);
        $info['token'] = $token;

        return $info;
    }

    /**
     * 切换身份.
     * @param array $params
     * @return bool
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-04-11 21:53
     */
    public
    function checkoutIdentity(array $params = []): bool
    {
        $platformId = $params['platform_id'] ?? '';
        if (empty($platformId)) {
            throw new Exception('平台id不存在');
        }

        if (self::getPlatformId() == TravelEnum::PLATFORM_DRIVER) {
            throw new Exception('司机身份不能切换');
        }

        //查询用户是否存在
        $user = VillagerUserModel::query()->where('id', request()->userId)->first();
        if (!$user) {
            throw new Exception('用户不存在');
        }

        $user->identity = $platformId;
        if (!$user->save()) {
            throw new Exception('切换身份失败');
        }

        return true;
    }

    /**
     * @return array
     * @throws Exception
     */
    public function checkoutList(): array
    {
        //查询openid是否存在
        $user = VillagerUserModel::query()->where('id', request()->userId)->first();
        if (!$user) {
            throw new Exception('用户不存在');
        }

        $where = [];
        $where[] = ['user_id', '=', request()->userId];
        $where[] = ['status', '=', 1];
        $where[] = ['user_type', '!=', TravelEnum::PLATFORM_DONATION];

        $result = VillagerUserCommunityModel::query()->where($where)->get()->toArray();
        $data = [];
        if (!empty($result)) {
            $communityId = 0;
            foreach ($result as $item) {
                // 合并村/居委，只与下面一行有关
                if( $item['user_type'] == TravelEnum::PLATFORM_VILLAGER_COMMITTEE ) continue;
                // 将捐赠者 后面统一添加
                if ($item['user_type'] == TravelEnum::PLATFORM_DONATION) continue;

                $communityId = $item['community_id'];

                $data[] = ['community_id'=>$communityId, 'status'=>$item['status'],'user_type' => $item['user_type'], 'platform_name' => TravelEnum::APP_PLATFORM_NAMES[$item['user_type']] ?? ''];
            }

            // 某些情况在身份表中没有 捐赠者数据，此处应该添加上去
            if (!empty($data)) {
                $data[] = [
                    'community_id'=>$communityId,
                    'status'=>1,
                    'user_type' => TravelEnum::PLATFORM_DONATION,
                    'platform_name' => TravelEnum::APP_PLATFORM_NAMES[TravelEnum::PLATFORM_DONATION],

                ];
            }
        }
        return $data;
    }


    /**
     * 微信登录
     * @param array $post
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-04-10 22:42
     */
    public function wxLogin(array $post = [])
    {
        //进行拿code获取openid
        $url = sprintf(config('wx.url'), $this->appId, $this->appKey, $post['code']);
        $data = curlGet($url);
        if ($data['errcode'] ?? 0) {
            throw new Exception($data['errmsg']);
        }
        //查询openid是否存在
        $user = VillagerUserModel::where('open_id', $data['openid'])->first();
        if (empty($user)) {
            $post['from'] = empty($post['from'])?VillagerEnum::USER_SOURCE_SELF:$post['from'];
            $data['from'] = in_array($post['from'],array_keys(VillagerEnum::USER_SOURCE_NAME))?VillagerEnum::USER_SOURCE_NAME[$post['from']]:VillagerEnum::USER_SOURCE_SELF;
            //新增 openid
            $user = VillagerUserService::addWxVillager($data);
            // 增加用户的钱包
            WalletService::createUserWallet($user);
            // 新用户直接取从村民之家取一次 用户信息 20231013 by LC
            if( !empty($user['phone']) )
                $this->_fetchUserInfo($user['id'],$user['phone']);
        } else {
            //修改 session_key
            $user->session_key = $data['session_key'];
            if (!$user->save()) {
                throw new Exception('登录失败');
            }
            $user = VillagerUserModel::where('open_id', $data['openid'])->first();
        }

        if ($user->status == VillagerEnum::ACCOUNT_STATUS_CANCELLATION) {
            throw new Exception('账号已注销');
        }
        // 村委会/居委会
        if (in_array($user->identity, [TravelEnum::PLATFORM_VILLAGER_COMMITTEE, TravelEnum::PLATFORM_MEMBER_VILLAGER])) {
            //检查是否审核通过
            $community = UserCommunityModel::query()
                ->where('user_id', $user->id)
                ->where('community_id', self::getPlatformId())
                ->first();
            if (!$community) {
                $user['is_check_community'] = false;
                $user['status'] = 0;
            } else {
                $user['is_check_community'] = true;
                $user['status'] = $community->status;
            }
        }

        $user['token'] = Jwt::createToken($user['id']);
        return $user;
    }

    /**
     * 微信 获取 Token
     * @return mixed
     * @author ycs 2023-08-03
     */
    public function wxSecretToken()
    {
        $appId  = env('WECHAT_APP_ID');
        $appKey = env('WECHAT_KEY');

        $secret['token'] = Jwt::createJwtToken($appId.'/'.$appKey);
        return $secret;
    }

    /**
     * 微信 获取 密钥
     * @param array $post
     * @return mixed
     * @throws Exception
     * @author ycs 2023-08-03
     */
    public function wxSecret(array $post = [])
    {
        $token  = trim($post['token']);

        if (!$token) {
            throw new Exception('token 无效');
        }

        $secret = Jwt::decodeToken($token);
        $str    = $secret['token'];

        unset($_dataArr, $dataArr);
        $dataArr = explode('/', $str);

        $_dataArr['appId']     = $dataArr[0];
        $_dataArr['appSecret'] = $dataArr[1];

        return $_dataArr;
    }

    /**
     * 获取配置时间
     * @return array
     */
    public function getConfigTime(): array
    {
        $config = AdminConfigModel::query()->first();
        if (!$config) {
            return [];
        }

        $config = $config->toArray();
        $threeTime = $config['contact_time'] ?? 3;
        $config['start_time'] = date('Y-m-d H:i:s', strtotime(date('Y-m-d H:i:s', time()) . " +$threeTime hours"));
        $config['time_limit_hour'] = $config['time_limit_hour'] ?? 72;

        return $config;
    }
    public static function getVehicleConfig( $params )
    {
        $cityCode       = $params['city_code'];
        $platformId     = $params['platform_id'];
        $payment        = $params['payment'];
        $excludeUseType = $params['exclude_use_type'] ?? [];
        $specifiedUseType    = $params['specified_use_type'] ?? [];

        // 获取所有车型
        $row = ConfigModel::query()->where('name', 'vehicle_type')->first();
        if( !$row ) return false;
        $vehicleType  = $row->toArray();$vehicleType = json_decode($vehicleType['value'],true);

        // 1.1 获取所有用车类型
        $row = ConfigModel::query()->where('name', 'vehicle_use_type')->first();
        if( !$row ) return false;
        $vehicleUseType  = $row->toArray();
        $vehicleUseType = json_decode($vehicleUseType['value'], true);

        // 1.1.1 去掉要排除的
        if( !empty($excludeUseType) ) {
            foreach( $vehicleUseType as $ut => $un)
                if( in_array($ut, $excludeUseType) )
                    unset($vehicleUseType[$ut]);
        }
        // 1.1.2 拿到的权含
        if( !empty($specifiedUseType) ) {
            foreach( $vehicleUseType as $ut=> $un )
                if( !in_array($ut, $specifiedUseType) )
                    unset($vehicleUseType[$ut]);
        }

        $where = [
            'status'    => VehicleConfigEnum::STATUS_OK,
            'payment'   => $payment,
            'up_stream' => $platformId,
            'city_code' => $cityCode
        ];

        $model = VehicleConfigModel::query()->select(['use_type', 'vehicle_type'])->where($where);
        if( !empty($vehicleUseType) ) $model = $model->whereIn('use_type', array_keys($vehicleUseType) );
        $rows = $model->orderBy('use_type', 'ASC')->get()->toArray();

        $newVehicleType = $newUseType = [];
        // 只输出配置了价格的数据
        foreach( $rows as $row)
        {
            $ut = $row['use_type']; $vt = $row['vehicle_type'];
            if( isset($vehicleUseType[$ut]) )   $newUseType[$ut]        = $vehicleUseType[$ut];
            if( isset($vehicleType[$vt]) )      $newVehicleType[$vt]    = $vehicleType[$vt];
        }

        return [$newVehicleType, $newUseType, $rows];
    }

    /**
     * 是否能联系司机
     * contactDriver
     * @param int $orderId
     * @return bool
     * @throws Exception
     * @author ninetyseven.
     * @date 2023/5/1
     */
    public function contactDriver(int $orderId = 0): bool
    {
        if (empty($orderId)) {
            throw new Exception('订单id不存在');
        }

        $order = OrderModel::query()->where('id', $orderId)->first();
        if (!$order) {
            throw new Exception('订单不存在');
        }

        $config = AdminConfigModel::query()->first();
        if (!$config) {
            return false;
        }

        $config = $config->toArray();
        $threeTime = $config['contact_time'] ?? 3;
        // 计算出发时间
        $departureTime = $order->start_time;
        // 计算当前时间
        $currentTime = time();
        // 如果出发时间已经过了，不允许联系司机
        if ($departureTime <= $currentTime) {
            return false;
        }

        // 计算出发前三个小时的时间
        $beforeDepartureTime = $departureTime - $threeTime * 3600;
        // 如果当前时间在出发前三个小时之内，允许联系司机
        return $currentTime >= $beforeDepartureTime;
    }

    /**
     * 注销用户
     * @param int $userId
     * @return true
     * @throws Exception
     */
    public
    function updateUserStatus(int $userId = 0): bool
    {
        //村民
        $user = VillagerUserModel::query()->where('id', $userId)->first();
        if (!$user) {
            throw new Exception('用户不存在');
        }

        $user->status = VillagerEnum::ACCOUNT_STATUS_CANCELLATION;

        if (!$user->save()) {
            throw new Exception('注销失败');
        }

        return true;
    }

    /**
     * 获取轮播图
     * @param array $params
     * @return \Illuminate\Database\Eloquent\Builder|mixed
     * @author ninetyseven.
     * @date 2023-03-30 22:25
     */
    public
    function getBannerList(array $params = [])
    {
        $platformId = self::getPlatformId();

        $where = [
            'platform_id' => $platformId,
            'is_active' => BannerEnum::IS_ACTIVE,
        ];

        if (!isset($params['is_driver'])) {
            $where['community_id'] = $params['community_id'];
        }
        return BannerModel::query()->where($where)->orderBy('order_number', 'desc')->get();
    }

    /**
     * 获取用户余额列表
     * @param array $params
     * @return array
     * @throws Exception
     * @author ninetyseven.
     * @date 2023-04-02 17:44
     */
    public function getWalletList(array $params = []): array
    {
        $where = [];
        if ($params['platform_id'] == TravelEnum::PLATFORM_DRIVER) {
            $where[] = ['user_type', '=', WalletsEnum::WALLET_USER_DRIVER];
            $idWhere[] = ['amount_type', '=', WalletsEnum::WALLET_MONEY_TYPE_DIGITAL];
            $idWhere[] = ['driver_id', '=', $params['user_id']];
        } else {
            $where[] = ['user_type', '=', WalletsEnum::WALLET_USER_VILLAGER];
            $idWhere[] = ['user_id', '=', $params['user_id']];
        }
        $userWallet = WalletModel::query()->where($where)->where('user_id',$params['user_id'])->select()->first();
        if (!$userWallet) {
            throw new Exception('用户不存在');
        }
        $userLogList = BalanceLogModel::query()->where($where)->where($idWhere)->select()->orderBy('created_at', 'desc')->get();
        return [
            'balance' => self::getPlatformId() == TravelEnum::PLATFORM_DONATION ? $userWallet['point_balance'] : $userWallet['digital_balance'],
            'list' => $userLogList ?? [],
        ];
    }

    /**
     * 余额变动
     * @param array $upData
     * @param array $where
     * @return int
     * @author ninetyseven.
     * @date 2023-04-05 18:49
     */
    public function changeInAmount(array $upData = [], array $where = []): int
    {
        return WalletModel::query()->where($where)->update($upData);
    }

    /**
     * 记录余额变动日志
     * @param array $data
     * @return int
     * @throws Exception
     */
    public static function recordAmountLog(array $data = []): int
    {
        $addData = [];
        $addData['user_id'] = $data['user_id'];
        $addData['order_no'] = $data['order_no'];
        $addData['change_type'] = $data['change_type'];
        $addData['amount_type'] = $data['amount_type'];
        $addData['amount'] = $data['amount'];
        $addData['order_type'] = $data['order_type'] ?? BalanceLogEnum::ORDER_TYPE_ORDER;
        $addData['comment'] = $data['comment'] ?? '';
// -----------以上字段必填
        $addData['user_type'] = $data['user_type'] ?? WalletsEnum::WALLET_USER_VILLAGER;
        $addData['driver_id'] = $data['driver_id'] ?? 0;
        $addData['start_address'] = $data['start_address'] ?? '-';
        $addData['start_time'] = $data['start_time'] ?? 0;
        $addData['end_address'] = $data['end_address'] ?? '-';
        $addData['end_time'] = $data['end_time'] ?? 0;

        $result = BalanceLogModel::query()->create($addData);
        if( empty($result) ){
            throw new Exception("添加balance_log失败");
        }
        return (int)$result->id;
    }

    /**
     * 调用阿里云OSS SDK
     * @param string $tmpName
     * @param string $ext
     * @param string $menu
     * @return array
     */
    public
    static function aliUploadFile(string $tmpName = '', string $ext = '', string $menu = 'image'): array
    {
        try {
            //获取OSS参数值
            $KeyId = env('ACCESS_KEY_ID');
            $KeySecret = env('ACCESS_KEY_SECRET');
            $EndPoint = env('END_POINT');
            $Bucket = env('BUCKET');
            $cnameUrl = env('OSS_URL');

            $options = [
                OssClient::OSS_HEADERS => [
                    'Content-Type' => 'image/jpg',
                ],
            ];

            //实例化
            $ossClient = new OssClient($KeyId, $KeySecret, $cnameUrl,true);
            //sha1加密 生成文件名 连接后缀
            $fileName = $menu . '/' . date('Ymd') . '/' . sha1(date('YmdHis', time()) . uniqid()) . '.' . $ext;
            //执行阿里云上传
            $result = $ossClient->uploadFile($Bucket, $fileName, $tmpName, $options);

            //图片地址:$result['info']['url']
            $data = [
                'full_url' => $result['info']['url'],
                'save_url' => $fileName
            ];
            $arr = ['code' => 200, 'msg' => '上传成功', 'data' => $data];
        } catch (OssException $e) {
            $arr = ['code' => 0, 'msg' => $e->getMessage(), 'data' => ''];
        }
        return $arr;
    }

    /**
     * 反馈
     * @param array $params
     * @return mixed
     * @author ninetyseven.
     * @date 2023-04-05 18:49
     */
    public function feedback(array $params)
    {
        $data['description'] = $params['description'];
        if (!empty($params['images'])) {
            $data['image'] = implode(',', $params['images']);
        }
        $data['user_id'] = request()->userId;

        return FeedbackModel::create($data);
    }

    /**
     * 获取当前用户的社区关系
     * @throws Exception
     */
    public static function getCommunity()
    {
        $userId = \request()->userId;
        $platformId = self::getPlatformId();

        $res = UserCommunityModel::query()
            ->where('user_id', $userId);

        if ($platformId != TravelEnum::PLATFORM_DONATION) {
            $res->where('user_type', $platformId);
        }
        $res = $res->where('status', 1)
            ->first();

        if (!$res) {
            throw new Exception('用户没有绑定社区');
        }
        return $res->toArray();
    }

    /**
     * 获取机场
     *
     * @param int $cityCode 城市代码
     * @return array
     */
    public static function getAirport(int $cityCode): array
    {
        $result = AirportModel::query()->where(['city_code'=>$cityCode, 'status'=>AirportEnum::STATUS_IN_USE])->get(['id', 'airport','adcode','longitude','latitude']);
        if (empty($result)) return [];
        else return $result->toArray();
    }

    /**
     * 订单发起局限在时间扣除金额
     *
     * @param int $startTime
     * @return int
     * @throws Exception
     */
    public static function getLimitTimeMoney(int $startTime): int
    {
        $config = AdminConfigModel::query()->first();
        if (!$config) {
            throw new Exception('平台配置不存在');
        }
        //当前时间和指定时间的时间戳差分钟数
        $minute = (time() - $startTime) / 60;
        //超过指定时间扣除金额
        switch ($minute) {
            case $minute <= $config['cancel_order_minute_case1']:
                $money = $config['cancel_order_num_case1'];
                break;
            case $minute < $config['cancel_order_num_case2']:
                $money = $config['cancel_order_minute_case2'];
                break;
            case $minute > $config['cancel_order_num_case3']:
                $money = $config['cancel_order_minute_case3'];
                break;
            default:
                $money = 0;
        }
        return $money;
    }

    /**
     * 可以抢单的司机
     * seizeOrders
     * @param $orderInfo
     * @return array
     * @throws Exception
     * @author ninetyseven.
     * @date 2023/5/2
     */
    public
    static function seizeOrders($orderInfo): array
    {
        $startTime = $orderInfo['start_time'];
        $startTime = is_string($startTime) ? strtotime($startTime) : $startTime;
        if (!$startTime) {
            throw new Exception('订单时间错误');
        }
        //根据starttime获取半小时后的时间
        $endTime = strtotime('+30 minutes', $startTime);

        /*订单的起始时间和结束时间可能与时间段存在交叉，所以使用了  whereBetween()  方法和  orWhere()  方法进行查询。
        如果查询结果大于 0，则说明该时间段内存在订单，司机不能接单；
        否则说明该时间段内不存在订单，司机可以接单。 */
        $order = OrderModel::query()->where('status', '=', OrderEnum::STATUS_DRIVING)
            ->where(function ($query) use ($startTime, $endTime) {
                $query->whereBetween('start_time', [$startTime, $endTime])
                    ->orWhereBetween('end_time', [$startTime, $endTime])
                    ->orWhere(function ($query) use ($startTime, $endTime) {
                        $query->where('start_time', '<=', $startTime)
                            ->where('end_time', '>=', $endTime);
                    });
            })->get()->toArray();

        $driverIds = [];
        if ($order) {
            //该司机集合不能抢单
            $driverIds = array_column($order, 'driver_id');
        }

        //司机未在上班时间 || 司机状态修改为下线 两种情况都不能抢单
        $driverOff = DriverModel::query()->where(function ($query) {
            $query->where('status', DriverEnum::DRIVER_STATUS_OFF)
                ->orWhere('status', DriverEnum::DRIVER_STATUS_DRIVING);
        })->get()->toArray();
        if ($driverOff) {
            //该司机集合不能抢单
            $driverOff = array_column($driverOff, 'driver_id');
            $driverIds = array_merge($driverIds, $driverOff);
        }

        // 判断司机是否在上班时间
        $start24Time = date('H', $startTime);
        $end24Time = date('H', $endTime);

        $driverTimeData = DriverModel::query()->where('go_on_work_time', '<=', $start24Time)
            ->where('go_off_work_time', '>=', $end24Time)->get()->toArray();
        if ($driverTimeData) {
            //该司机集合不能抢单
            $driverOff = array_column($driverTimeData, 'driver_id');
            $driverIds = array_merge($driverIds, $driverOff);
        }

        return DriverModel::query()->whereNOTIn('id', $driverIds)->get()->toArray();
    }

    /**
     * SDK活体检测结果查询
     * @param array $param
     * @throws GuzzleException
     */
    public function getFaceVerify(array $param = [])
    {
        $res = json_decode((new ShuMaiDataClient())->facePhotos($param['packageName'], $param['signData']), true);
        if ($res['code'] != 200) {
            throw new Exception($res['msg']);
        }
        $param['image'] = $res['data']['faceImage'];
        $result = $this->faceIdCardCompare($param);
        if ($result['score'] < 0.45) {
            throw new Exception('人脸识别失败');
        }
        return $result;
    }

    /**
     * 人脸身份证比对
     * @param array $param
     * throws Exception
     * @throws GuzzleException
     */
    public function faceIdCardCompare(array $param = [])
    {
        $user = DriverRealModel::query()->where(['driver_id' => request()->userId])->first();
        if (!$user) {
            throw new Exception('用户不存在');
        }

        $data = json_decode((new ShuMaiDataClient())->faceIdCardCompare(
            $user->identity_card,
            $user->real_name,
            $param['image'] ?? null,
            $param['url'] ?? null), true);

        if ($data['code'] != 200) {
            throw new Exception($data['msg']);
        }
        return $data['data'];
    }
}
